﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Xml.Linq;
using Microsoft.SharePoint;
using System.Text.RegularExpressions;

namespace LizardSoft.Common.FlexibleStructureDeployment
{
    public static partial class StructureHelper
    {
        /// <summary>
        /// Корректировка столбцов-сайта подстановок
        /// </summary>
        /// <param name="siteUrl">Url-адрес сайтовой коллекции</param>
        /// <param name="fieldNames">Массив внутренних названий столбцов</param>
        public static void CorrectSiteLookupFields(string siteUrl, string[] fieldNames)
        {
            SPSite site = null;
            try
            {
                site = new SPSite(siteUrl);
                SPWeb rootWeb = site.RootWeb;
                foreach (string fieldName in fieldNames)
                {
                    SPField lookupField = rootWeb.Fields.TryGetFieldByStaticName(fieldName);
                    if (lookupField != null)
                    {
                        try
                        {
                            // получаем схему поля
                            XDocument fieldSchema = XDocument.Parse(lookupField.SchemaXml);
                            XElement root = fieldSchema.Root;

                            XAttribute attrWebId = root.Attribute("WebId");
                            XAttribute attrList = root.Attribute("List");
                            if (attrList != null)
                            {
                                string listUrl = root.Attribute("List").Value;
                                SPFolder listFolder = null;
                                SPWeb lookupWeb = null;
                                try
                                {
                                    if (attrWebId == null)
                                    {
                                        // ищем список на корневом вебе
                                        listFolder = rootWeb.GetFolder(listUrl);
                                        // добавляем WebId, чтобы поле можно было использовать на подсайтах
                                        XName webIdName = XName.Get("WebId", attrList.Name.NamespaceName);
                                        root.SetAttributeValue(webIdName, rootWeb.ID.ToString("D"));
                                    }
                                    else
                                    {
                                        if (String.IsNullOrEmpty(attrWebId.Value))
                                        {
                                            throw new Exception(
                                                "Параметр WebId содержит пустое значение. Укажите значение или удалите этот параметр из схемы поля");
                                        }
                                        // ищем список на другом вебе
                                        lookupWeb = site.OpenWeb(attrWebId.Value);
                                        if (!lookupWeb.Exists)
                                        {
                                            throw new Exception(String.Format("Веб-сайт по strUrl {0} не найден", attrWebId.Value));
                                        }
                                        attrWebId.Value = lookupWeb.ID.ToString("D");
                                        listFolder = lookupWeb.GetFolder(listUrl);
                                    }

                                    if (listFolder != null && listFolder.Exists)
                                    {
                                        attrList.Value = listFolder.ParentListId.ToString("B");
                                        // перезаписываем схему поля
                                        lookupField.SchemaXml = fieldSchema.ToString();
                                        lookupField.Update(true);
                                    }
                                    else throw new Exception(String.Format("Список {0} не найден", listUrl));
                                }
                                catch { throw; }
                                finally
                                {
                                    if (lookupWeb != null) lookupWeb.Dispose();
                                }
                            }
                            else throw new Exception("Параметр List не указан");
                        }
                        catch (Exception ex)
                        {
                            string message = String.Format("Ошибка обновления поля {0}: {1}", fieldName, ex.Message);
                            throw new Exception(message, ex);
                        }
                    }
                    else throw new Exception(String.Format("Столбец-подстановка {0} не найден", fieldName));
                }
            }
            catch (Exception ex) 
            {
                throw new Exception(String.Format("CorrectSiteLookupFields: {0}", ex.ToString()), ex); 
            }
            finally
            {
                if (site != null) site.Dispose();
            }            
        }
    }
}
